/**********************************************
*  Classes:   SceneNode
*  Desc:      Abstract class that defines a node
*			  in the Scene Graph
*  Author:    Vaios Kalpias-Ilias (C) 2008-2009
***********************************************/

#include "SceneNode.h"

//-------------------------------------------------
/**
* Ctor
*/
SceneNode::SceneNode() : m_pParent(0)					
{
	
}
//-------------------------------------------------
/**
* Dtor
*/
SceneNode::~SceneNode()
{
	Destroy();
}
//-------------------------------------------------
/**
* Returns type
*/
const SceneNode::NodeType SceneNode::GetType() const
{
	return NODE_DEFAULT;
}
//-------------------------------------------------
/**
* Updates children
*/
void SceneNode::Update()
{
	PreUpdate();

	std::list<SceneNodePtr>::iterator it;
	for (it = m_lChildren.begin();
		it != m_lChildren.end();
		++it)
	{
		(*it)->Update();
	}

	PostUpdate();
}
//-------------------------------------------------
/**
* Detaches all children
*/
void SceneNode::DetachAllChildren()
{
	m_lChildren.clear();
}
//-------------------------------------------------
/**
* Detaches parent node
*/
void SceneNode::DetachParent()
{
	GetParent()->DetachChild(SceneNodePtr(this));
}
//-------------------------------------------------
/**
* Attaches child
*/
void SceneNode::AttachChild(SceneNodePtr node)
{
	if (node)
	{
		m_lChildren.push_back(node);
		node->m_pParent = this;
	}
}
//-------------------------------------------------
/**
* Detatches child
*/
void SceneNode::DetachChild(SceneNodePtr node)
{
	if (node)
	{
		m_lChildren.remove(node);
		node->m_pParent = 0;
	}
}
//-------------------------------------------------
/**
* Destroys all children
*/
void SceneNode::Destroy()
{
	
	std::list<SceneNodePtr>::iterator it = m_lChildren.begin();
	for (;
		it != m_lChildren.end();
		++it)
	{
		DestroyChild(*it);//->Release();
	}

	m_lChildren.clear();

	m_pParent = 0;
}

void SceneNode::DestroyChild(SceneNodePtr child)
{
	const NodeList& children = child->GetChildren();
	NodeList::const_iterator it = children.begin();
	for (; it != children.end(); ++it)
	{
		DestroyChild(*it);
	}

	child->m_lChildren.clear();
	child->m_pParent = 0;
}